package com.rssreader.playtts;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.BreakIterator;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;

import org.json.JSONException;
import org.json.JSONObject;

import android.R;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnBufferingUpdateListener;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.os.Handler;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.SeekBar;
import android.widget.TextView;

public class TTS implements OnPreparedListener, OnClickListener,
		OnTouchListener, OnCompletionListener, OnBufferingUpdateListener {
	private TextView textStreamed;
	private final Handler handler;

	private ImageButton playButton;

	private SeekBar seekBar;

	private Context context;
	private MediaPlayer mediaPlayer;
	private File downloadingMediaFile;

	private FileInputStream fileInputStream;

	private int mediaFileLengthInMilliseconds;

	public TTS(Context context, TextView textStreamed,
			ImageButton buttonPlayAndPause, Button buttonRead, SeekBar seekBar, Handler handler) {
		this.context = context;
		this.playButton = buttonPlayAndPause;
		this.textStreamed = textStreamed;
		this.seekBar = seekBar;
		this.handler = handler;
		mediaPlayer = new MediaPlayer();
		mediaPlayer.setOnBufferingUpdateListener(this);
		mediaPlayer.setOnCompletionListener(this);
	}

	public void startMediaStream(String text)
			throws MalformedURLException, IOException, JSONException {
		List<String> sentences = splitSentence(text);
		String mediaUrl = "http://192.168.5.1:8080/VoiceNewsServer/rest/ttsservices/audio";
		downloadingMediaFile = new File(context.getCacheDir(),
				"downloadingMedia.dat");

		// Just in case a prior deletion failed because our code crashed or
		// something, we also delete any previously
		// downloaded file to ensure we start fresh. If you use this code,
		// always delete
		// no longer used downloads else you'll quickly fill up your hard disk
		// memory. Of course, you can also
		// store any previously downloaded file in a separate data cache for
		// instant replay if you wanted as well.
		if (downloadingMediaFile.exists()) {
			downloadingMediaFile.delete();
		}

		FileOutputStream out = new FileOutputStream(downloadingMediaFile);
		byte buf[] = new byte[16384];

		for (Iterator<String> iterator = sentences.iterator(); iterator
				.hasNext();) {
			String sentence = (String) iterator.next();
			HttpURLConnection cn = (HttpURLConnection) new URL(mediaUrl)
					.openConnection();

			cn.addRequestProperty("User-Agent",
					"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)");
			cn.setRequestProperty("Content-Type", "application/json");

			((HttpURLConnection) cn).setRequestMethod("POST");
			cn.setDoOutput(true);
			// cn.setDoInput(true);
			JSONObject data = new JSONObject();
			data.put("data", sentence);
			OutputStreamWriter wr = new OutputStreamWriter(cn.getOutputStream());
			wr.write(data.toString());
			wr.close();
			cn.connect();
			InputStream stream = cn.getInputStream();
			do {
				int numread = stream.read(buf);
				if (numread <= 0)
					break;
				out.write(buf, 0, numread);
			} while (true);

			stream.close();
		}

		out.close();

		fileInputStream = new FileInputStream(downloadingMediaFile);
		mediaPlayer.setDataSource(fileInputStream.getFD());
		mediaPlayer.setOnPreparedListener(this);
		mediaPlayer.prepareAsync();
		fileInputStream.close();
	}

	public List<String> splitSentence(String string) {
		List<String> strings = new ArrayList<String>();
		BreakIterator iterator = BreakIterator.getSentenceInstance(Locale.US);
		iterator.setText(string);
		int start = iterator.first();
		for (int end = iterator.next(); end != BreakIterator.DONE; start = end, end = iterator
				.next()) {
			String sentence = string.substring(start, end);
			strings.add(sentence);
		}

		return strings;
	}

	@Override
	public void onPrepared(MediaPlayer mp) {
		// TODO Auto-generated method stub
		mp.start();
		mediaFileLengthInMilliseconds = mediaPlayer.getDuration();
		System.out.println(mediaFileLengthInMilliseconds);
		primarySeekBarProgressUpdater();
	}

	@Override
	public void onBufferingUpdate(MediaPlayer arg0, int arg1) {
		// TODO Auto-generated method stub
		seekBar.setSecondaryProgress(arg1);
	}

	@Override
	public void onCompletion(MediaPlayer arg0) {
		// TODO Auto-generated method stub
		playButton.setImageResource(R.drawable.ic_media_play);
	}

	@Override
	public boolean onTouch(View v, MotionEvent event) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void onClick(DialogInterface dialog, int which) {
		// TODO Auto-generated method stub

	}

	/**
	 * Method which updates the SeekBar primary progress by current song playing
	 * position
	 */
	private void primarySeekBarProgressUpdater() {
		seekBar.setProgress((int) (((float) mediaPlayer
				.getCurrentPosition() / mediaFileLengthInMilliseconds) * 100)); // This
																				// math
																				// construction
																				// give
																				// a
																				// percentage
																				// of
																				// "was playing"/"song length"
		if (mediaPlayer.isPlaying()) {
			Runnable notification = new Runnable() {
				public void run() {
					primarySeekBarProgressUpdater();
				}
			};
			handler.postDelayed(notification, 1000);
		}
	}

	public MediaPlayer getMediaPlayer() {
		return mediaPlayer;
	}

	public void setMediaPlayer(MediaPlayer mediaPlayer) {
		this.mediaPlayer = mediaPlayer;
	}
	
	

}
